{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "6cd1da16",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "031bf62f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1获取数据集\n",
    "data = pd.read_csv(\"./FacebookData/train.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "750003a5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>row_id</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>accuracy</th>\n",
       "      <th>time</th>\n",
       "      <th>place_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0.7941</td>\n",
       "      <td>9.0809</td>\n",
       "      <td>54</td>\n",
       "      <td>470702</td>\n",
       "      <td>8523065625</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>5.9567</td>\n",
       "      <td>4.7968</td>\n",
       "      <td>13</td>\n",
       "      <td>186555</td>\n",
       "      <td>1757726713</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>8.3078</td>\n",
       "      <td>7.0407</td>\n",
       "      <td>74</td>\n",
       "      <td>322648</td>\n",
       "      <td>1137537235</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>7.3665</td>\n",
       "      <td>2.5165</td>\n",
       "      <td>65</td>\n",
       "      <td>704587</td>\n",
       "      <td>6567393236</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>4.0961</td>\n",
       "      <td>1.1307</td>\n",
       "      <td>31</td>\n",
       "      <td>472130</td>\n",
       "      <td>7440663949</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   row_id       x       y  accuracy    time    place_id\n",
       "0       0  0.7941  9.0809        54  470702  8523065625\n",
       "1       1  5.9567  4.7968        13  186555  1757726713\n",
       "2       2  8.3078  7.0407        74  322648  1137537235\n",
       "3       3  7.3665  2.5165        65  704587  6567393236\n",
       "4       4  4.0961  1.1307        31  472130  7440663949"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "f3b4a379",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\huishi\\AppData\\Local\\Temp\\ipykernel_17328\\3040597234.py:13: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_final[\"year\"] = data_final[\"new_time\"].dt.year\n",
      "C:\\Users\\huishi\\AppData\\Local\\Temp\\ipykernel_17328\\3040597234.py:14: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_final[\"month\"] = data_final[\"new_time\"].dt.month\n",
      "C:\\Users\\huishi\\AppData\\Local\\Temp\\ipykernel_17328\\3040597234.py:15: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_final[\"day\"] = data_final[\"new_time\"].dt.day\n",
      "C:\\Users\\huishi\\AppData\\Local\\Temp\\ipykernel_17328\\3040597234.py:16: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_final[\"hour\"] = data_final[\"new_time\"].dt.hour\n",
      "C:\\Users\\huishi\\AppData\\Local\\Temp\\ipykernel_17328\\3040597234.py:17: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_final[\"minute\"] = data_final[\"new_time\"].dt.minute\n",
      "C:\\Users\\huishi\\AppData\\Local\\Temp\\ipykernel_17328\\3040597234.py:18: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  data_final[\"second\"] = data_final[\"new_time\"].dt.second\n"
     ]
    }
   ],
   "source": [
    "# 2 数据预处理\n",
    "# 1)时间处理\n",
    "time_column = pd.to_datetime(data[\"time\"],unit=\"s\")\n",
    "time_column\n",
    "data[\"new_time\"] = time_column\n",
    "\n",
    "# 2)过滤掉签到次数少的\n",
    "place_count = data.groupby(\"place_id\").count()[\"x\"]\n",
    "data_final = data[data[\"place_id\"].isin(place_count[place_count > 3].index.values)]\n",
    "\n",
    "# 3）时间特征抽取\n",
    "# 现在new_time是 1970-01-08 05:06:14 datetime64[ns] 类型的 不利于算法理解，将其转成年月日 时分秒\n",
    "data_final[\"year\"] = data_final[\"new_time\"].dt.year\n",
    "data_final[\"month\"] = data_final[\"new_time\"].dt.month\n",
    "data_final[\"day\"] = data_final[\"new_time\"].dt.day\n",
    "data_final[\"hour\"] = data_final[\"new_time\"].dt.hour\n",
    "data_final[\"minute\"] = data_final[\"new_time\"].dt.minute\n",
    "data_final[\"second\"] = data_final[\"new_time\"].dt.second\n",
    "\n",
    "data_final.head()\n",
    "# 3 数据集划分\n",
    "# 数据集太大 跑不动 \n",
    "data_final = data_final.query(\"x < 2.5 & x > 2 & y < 1.5 & y > 1.0\")\n",
    "\n",
    "x = data_final[[\"x\",\"y\",\"accuracy\",\"year\",\"month\",\"day\",\"hour\",\"minute\",\"second\"]]\n",
    "y = data_final[\"place_id\"]\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "x_train,x_test,y_train,y_test = train_test_split(x,y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "id": "9f310ac0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 4特征工程 \n",
    "# 特征预处理 标准化\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "transform = StandardScaler()\n",
    "x_train = transform.fit_transform(x_train)\n",
    "x_test = transform.transform(x_test)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "65de61dc",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\D_APP\\Anaconda3\\Lib\\site-packages\\sklearn\\model_selection\\_split.py:700: UserWarning: The least populated class in y has only 1 members, which is less than n_splits=3.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-2 {color: black;background-color: white;}#sk-container-id-2 pre{padding: 0;}#sk-container-id-2 div.sk-toggleable {background-color: white;}#sk-container-id-2 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-2 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-2 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-2 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-2 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-2 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-2 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-2 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-2 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-2 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-2 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-2 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-2 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-2 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-2 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-2 div.sk-item {position: relative;z-index: 1;}#sk-container-id-2 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-2 div.sk-item::before, #sk-container-id-2 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-2 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-2 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-2 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-2 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-2 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-2 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-2 div.sk-label-container {text-align: center;}#sk-container-id-2 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-2 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-2\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>GridSearchCV(cv=3, estimator=KNeighborsClassifier(),\n",
       "             param_grid={&#x27;n_neighbors&#x27;: [3, 5, 7, 9]})</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-4\" type=\"checkbox\" ><label for=\"sk-estimator-id-4\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">GridSearchCV</label><div class=\"sk-toggleable__content\"><pre>GridSearchCV(cv=3, estimator=KNeighborsClassifier(),\n",
       "             param_grid={&#x27;n_neighbors&#x27;: [3, 5, 7, 9]})</pre></div></div></div><div class=\"sk-parallel\"><div class=\"sk-parallel-item\"><div class=\"sk-item\"><div class=\"sk-label-container\"><div class=\"sk-label sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-5\" type=\"checkbox\" ><label for=\"sk-estimator-id-5\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">estimator: KNeighborsClassifier</label><div class=\"sk-toggleable__content\"><pre>KNeighborsClassifier()</pre></div></div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-6\" type=\"checkbox\" ><label for=\"sk-estimator-id-6\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">KNeighborsClassifier</label><div class=\"sk-toggleable__content\"><pre>KNeighborsClassifier()</pre></div></div></div></div></div></div></div></div></div></div>"
      ],
      "text/plain": [
       "GridSearchCV(cv=3, estimator=KNeighborsClassifier(),\n",
       "             param_grid={'n_neighbors': [3, 5, 7, 9]})"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 5选择算法学习 k-近邻\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "estimator = KNeighborsClassifier()\n",
    "# 加入交叉验证 和 网格验证\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "# k-近邻算法的超参数\n",
    "param_grid = {\"n_neighbors\":[3,5,7,9]}\n",
    "estimator = GridSearchCV(estimator,param_grid=param_grid,cv=3)\n",
    "# 开始学习\n",
    "estimator.fit(x_train,y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "4bba3338",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试值标签：\n",
      " 12864270    1533408099\n",
      "15235805    5943393344\n",
      "3646367     2739683636\n",
      "2313770     2571962720\n",
      "10392469    4374582281\n",
      "               ...    \n",
      "16498174    5567189582\n",
      "11154000    7942373049\n",
      "9352776     2607294907\n",
      "21399669    7810150060\n",
      "3318689     9773056775\n",
      "Name: place_id, Length: 20799, dtype: int64\n",
      "预测值标签：\n",
      " [1533408099 2585551753 3910675283 ... 1732563460 7929669489 1804841714]\n",
      "模型评估方法1，直接比较预测值和实际值：\n",
      " 12864270     True\n",
      "15235805    False\n",
      "3646367     False\n",
      "2313770     False\n",
      "10392469    False\n",
      "            ...  \n",
      "16498174    False\n",
      "11154000    False\n",
      "9352776     False\n",
      "21399669    False\n",
      "3318689     False\n",
      "Name: place_id, Length: 20799, dtype: bool\n",
      "模型评估方法2，计算准确率：\n",
      " 0.21669311024568488\n"
     ]
    }
   ],
   "source": [
    "# 6模型评估\n",
    "y_predict = estimator.predict(x_test)\n",
    "\n",
    "print(\"测试值标签：\\n\",y_test)\n",
    "print(\"预测值标签：\\n\",y_predict)\n",
    "print(\"模型评估方法1，直接比较预测值和实际值：\\n\", y_predict == y_test)\n",
    "\n",
    "print(\"模型评估方法2，计算准确率：\\n\", estimator.score(x_test, y_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "5b4e7f70",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 0.49209672,  1.65047438, -0.71923444, ..., -1.52511889,\n",
       "        -0.31332101,  0.60574346],\n",
       "       [ 0.43659726, -0.09256629, -0.12620256, ..., -1.37991368,\n",
       "         0.83883437,  0.43233657],\n",
       "       [-0.23147742, -0.12025674, -0.40527639, ..., -1.67032409,\n",
       "         1.29969652,  1.6461848 ],\n",
       "       ...,\n",
       "       [-0.49024362, -0.63908824, -0.18724996, ..., -0.21827206,\n",
       "         1.12687321, -0.72370936],\n",
       "       [-0.24049608, -1.5069651 , -0.06515516, ..., -0.21827206,\n",
       "        -0.94700646,  0.54794117],\n",
       "       [ 0.90071145,  0.10418161, -0.68435021, ..., -0.65388767,\n",
       "        -0.60135985,  0.37453428]])"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_test"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
